﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //Party zs = new Party("张三");
            //Party ls = new Party("李四");
            //Party ww = new Party("王五");
            ////声明委托注意参数就是一个方法名
            //MyDelegage zsDelegate = new MyDelegage(zs.Eat);
            //MyDelegage lsDelegate = new MyDelegage(ls.Eat);
            //MyDelegage wwDelegate = new MyDelegage(ww.Eat);

            //调用方法
            //zsDelegate("西瓜");
            //lsDelegate("西瓜");
            //wwDelegate("西瓜");
            //MyDelegage myde=null;
            //Console.WriteLine("张三，李四，王五开座谈会");
            //myde = zsDelegate + lsDelegate + wwDelegate;
            //myde("西瓜");
            //eachEat("西瓜", zsDelegate, lsDelegate, wwDelegate);
            //Console.WriteLine("李四接电话去了");
            //myde -= lsDelegate;
            //myde("冬瓜");
            //eachEat("冬瓜", zsDelegate, wwDelegate);
            //实例化出版社和读者
            //Publisher pub = new Publisher();
            //Subscriber zs = new Subscriber("张三");
            //Subscriber ls = new Subscriber("李四");

            ////向事件发行者订阅一个事件
            //pub.OnPubComputer += new Publisher.PubComputer(zs.Receive);
            //pub.OnPubLife += new Publisher.PubLife(zs.Receive);
            //pub.OnPubComputer += new Publisher.PubComputer(ls.Receive);
            //pub.OnPubLife += new Publisher.PubLife(ls.Receive);
            //pub.issueComputer();
            //pub.issueLife();
            //Console.WriteLine("一年以后！");
            //pub.OnPubLife -= new Publisher.PubLife(zs.Receive);
            //pub.issueLife();
            Publisher1 pub1 = new Publisher1();
            Subscriber1 zs = new Subscriber1("张三");

            pub1.PubComputer += new Publisher1.PubComputerEventHander(zs.Recive);
            pub1.isSue("电脑",DateTime.Now);
            Console.ReadLine();
        }

        private static void eachEat(string p, params MyDelegage[] wt)
        {
            if (wt == null)
                Console.WriteLine("座谈会结束");
            MyDelegage mydel = null;
            foreach (MyDelegage item in wt)
            {
                mydel += item;//添加委托链
            }
            //实现委托
            mydel(p);
        }
    }
    //定义委托，在能定义类的地方都能定义委托，但是返回类型和参数必须和需要代理的方法一致
    delegate void MyDelegage(string food);

    class Party
    {
        private string name;
        public Party(string name)
        {
            this.name = name;
        }

        public void Eat(string food)
        {
            Console.WriteLine(name + "吃" + food);
        }
    }

    /// <summary>
    /// 出版社：事件发行者
    /// </summary>
    class Publisher
    {
        //定义委托电脑杂志
        public delegate void PubComputer(string computer);
        //定义委托发行生活杂志
        public delegate void PubLife(string life);
        //定义事件
        public event PubComputer OnPubComputer;
        public event PubLife OnPubLife;
        //发行事件的触发方法
        public void issueComputer()
        {
            //检查事件
            if (OnPubComputer != null)
            {
                Console.WriteLine("出版社发行电脑杂志");
                OnPubComputer("电脑杂志");//事件执行
            }
        }
        public void issueLife()
        {
            if (OnPubLife != null)
            {
                Console.WriteLine("出版社发行生活杂志");
                OnPubLife("生活杂志");
            }
        }
    }
    /// <summary>
    /// 读者
    /// </summary>
    class Subscriber
    {
        private string name;

        public Subscriber(string name)
        {
            this.name = name;
        }
        //读者反馈信息（该方法的参数和返回类型必须和事件发行者定义的委托一致）
        public void Receive(string zz)
        {
            Console.WriteLine("读者" + name + "收到" + zz + "！");
        }
    }

    class PubComputerEventArgs : EventArgs
    {
        private readonly string _mazname;
        private readonly DateTime _pudate;
        public PubComputerEventArgs(string mazname, DateTime pudate)
        {
            this._mazname = mazname;
            this._pudate = pudate;
        }
        public string Mazname { get; set; }
        public DateTime Pudate { get; set; }
    }

    /// <summary>
    /// 出版社：事件发行者
    /// </summary>
    class Publisher1
    {
        //定义委托
        public delegate void PubComputerEventHander(object sender, PubComputerEventArgs e);
        //1在事件发行者中定义事件
        public event PubComputerEventHander PubComputer;
        //定义引发事件的方法：注意使访问权限 
        protected virtual void OnPubComputer(PubComputerEventArgs e)
        {
            PubComputerEventHander hander = PubComputer;//防止线程同步问题
            if (hander!=null)
            {
                hander(this, e);
            }
        }
        //2在事件发行者中触发事件
        public void isSue(string maz,DateTime dt)
        {
            if (PubComputer != null)
            {
                Console.WriteLine("出版社发行电脑杂志！");
                OnPubComputer(new PubComputerEventArgs(maz, dt));
            }
        }
    }
    /// <summary>
    /// 读者：事件订阅者
    /// </summary>
    class Subscriber1
    {
        private readonly string name;
        public Subscriber1(string name)
        {
            this.name = name;
        }
        //3事件订阅者处理事件处理程序 
        public void Recive(object sender, PubComputerEventArgs e)
        {
            Console.WriteLine(name + "在" + e.Pudate + "收到" + e.Mazname);
        }
    }
}
